package server

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
	"time"
)

const (
	broadcastPort = 8888 // 广播监听端口
	serverPort    = 8889 // 服务器监听端口
	timeout       = 30   // 搜索超时时间(秒)
)

func StartServer() {
	fmt.Println("=== UDP广播服务器 ===")

	// 搜索服务器
	clientAddr := discoverServer()
	if clientAddr == nil {
		fmt.Println("未找到客户端")
		return
	}

	fmt.Printf("收到客户端: %s\n", clientAddr.String())

	// 与建立连接
	connectToClient(clientAddr)

	// 保持程序运行
	select {}
}

// 发现客户端
func discoverServer() *net.UDPAddr {
	// 创建UDP广播监听地址
	broadcastAddr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf(":%d", broadcastPort))
	if err != nil {
		fmt.Printf("解析广播地址失败: %v\n", err)
		return nil
	}

	// 创建UDP监听
	conn, err := net.ListenUDP("udp4", broadcastAddr)
	if err != nil {
		fmt.Printf("监听广播失败: %v\n", err)
		return nil
	}
	defer conn.Close()

	// 设置读取超时
	conn.SetReadDeadline(time.Now().Add(timeout * time.Second))

	fmt.Printf("监听广播端口: %d (等待 %d 秒)\n", broadcastPort, timeout)

	buffer := make([]byte, 1024)

	for {
		// 接收广播消息
		n, addr, err := conn.ReadFromUDP(buffer)
		if err != nil {
			fmt.Printf("接收数据失败: %v\n", err)
			continue
		}

		message := string(buffer[:n])
		fmt.Printf("收到来自 %s 的广播: %s\n", addr.String(), message)

		return addr
	}
}

// 连接到客户端
func connectToClient(serverAddr *net.UDPAddr) {
	tcpAddr := &net.TCPAddr{
		IP:   serverAddr.IP,
		Port: serverPort,
	}

	// 创建TCP连接
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		fmt.Printf("连接客户端失败: %v\n", err)
		return
	}
	defer conn.Close()

	fmt.Println("已连接到客户端，可以开始发送消息 (输入 'exit' 退出)")

	// 启动接收消息的协程
	go receiveMessages(conn)

	// 读取用户输入并发送
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		message := scanner.Text()
		if strings.ToLower(message) == "exit" {
			break
		}

		// 发送消息到服务器
		_, err := conn.Write([]byte(message))
		if err != nil {
			fmt.Printf("发送消息失败: %v\n", err)
			continue
		}

		fmt.Printf("已发送: %s\n", message)
	}
}

// 接收服务器消息
func receiveMessages(conn *net.TCPConn) {
	buffer := make([]byte, 1024)
	for {
		n, err := conn.Read(buffer)
		if err != nil {
			fmt.Printf("接收消息失败: %v\n", err)
			continue
		}

		message := string(buffer[:n])
		fmt.Printf("\n收到回复: %s\n", message)
		fmt.Print("请输入消息: ")
	}
}

// 获取本机IP地址
func getLocalIP() string {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return ""
	}

	for _, addr := range addrs {
		if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				return ipnet.IP.String()
			}
		}
	}
	return ""
}
